package cn.kinoko.scheduled;

import cn.kinoko.model.ai.ocr.constant.OcrType;
import cn.kinoko.service.ai.ocr.OcrLrCalibrateService;
import cn.kinoko.service.common.CommonService;
import cn.kinoko.service.common.event.component.EventDistributeHandler;
import cn.kinoko.service.manga.MangaProcTaskService;
import cn.kinoko.service.manga.MangaService;
import cn.kinoko.service.minio.MinioService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * @author kinoko
 */
@Slf4j
@AllArgsConstructor
@EnableScheduling
@Component
public class ScheduledTask {

    private EventDistributeHandler eventDistributeHandler;
    private MinioService minioService;
    private MangaService mangaService;
    private CommonService commonService;
    private OcrLrCalibrateService ocrLrCalibrateService;
    private MangaProcTaskService mangaProcTaskService;

    /**
     * 每5秒分发一次事件
     */
    @Scheduled(cron = "0/5 * * * * ?")
    public void distributeEvent() {
        eventDistributeHandler.listenAndDistributeEvent();
    }

    /**
     * 每天0点清理无引用文件
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void clearNoReferenceFile() {
        log.info("[Scheduled]: 无引用文件清理任务执行...");
        minioService.clearNoReferenceFile();
    }

    /**
     * 每天0点清理逻辑删除数据
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void clearLogicDelData() {
        log.info("[Scheduled]: 逻辑删除数据清理任务执行...");
        commonService.clearLogicDelData();
    }

    /**
     * 每天0点计算漫画热度
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void computeMangaHeat() {
        log.info("[Scheduled]: 漫画热度计算任务执行...");
        mangaService.computeMangaHeat();
    }

    /**
     * 每5分钟计算一次OCR线性回归系数
     */
    @Scheduled(cron = "0 */5 * * * ?")
    public void computeOcrLrCoefficient() {
        log.info("[Scheduled]: OCR线性回归系数计算任务执行...");
        ocrLrCalibrateService.calibrate(OcrType.MIT);
    }

    /**
     * 每周一触发
     */
    @Scheduled(cron = "0 0 0 * * 1")
    public void weekSchedule() {
        log.info("[Scheduled]: 7日周期任务执行...");
        ocrLrCalibrateService.clearNotCalibrateData(OcrType.MIT);
    }

    /**
     * 每5分钟执行一次标记任务
     */
    @Async("markScheduler")
    @Scheduled(cron = "0 */5 * * * ?")
    public void autoMarkingSchedule() {
        log.info("[Scheduled]: AI自动标记任务执行...");
        mangaProcTaskService.markManga();
    }

    /**
     * 每5分钟执行一次标记任务
     */
    @Async("cutoutScheduler")
    @Scheduled(cron = "0 */5 * * * ?")
    public void autoCutoutSchedule() {
        log.info("[Scheduled]: AI自动抠图任务执行...");
        mangaProcTaskService.cutoutManga();
    }
}
